package thread;

public class Demo22 {
    public static void main(String[] args) throws InterruptedException {
        Object locker1 = new Object();
        Object locker2 = new Object();
        /*
         * 死锁形成条件
         * 1. 锁的不可剥夺性
         * 2. 互斥性
         * 3. 在调入一个锁的时候 同时调入另一个锁
         * 4. 循环等待
         */
        /*
         * 解决：
         * 1. 如果是自己实现的锁 那么上诉一二这两个条件是可以克服的
         * 2. 针对于3 直接将两个锁分开即可
         * 3. 如果无法分开 那么约定一下锁的调用顺序 只要都是顺序 那么就不会形成循环
         */
        // 方法1
        /*Thread t1 = new Thread(() -> {
            synchronized (locker1) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }
            synchronized (locker2) {
                System.out.println("t1 获取两把锁");
            }
        });

        Thread t2 = new Thread(() -> {
            synchronized (locker2) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            synchronized (locker1) {
                System.out.println("t2 获取两把锁");
            }
        });*/

        // 方法2 调换加锁顺序即可
        Thread t1 = new Thread(() -> {
            synchronized (locker1) {
                synchronized (locker2) {
                    System.out.println("t1 获取两把锁");
                }
            }
        });
        Thread t2 = new Thread(() -> {
            synchronized (locker1) {
                synchronized (locker2) {
                    System.out.println("t2 获取两把锁");
                }
            }
        });

        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}
